package face.detector;

import android.graphics.Bitmap;

import com.wis.util.StringUtils;

import face.entity.FaceFeaturePoint;
import face.entity.FaceFeatureRectangle;
import face.entity.FaceModel;

/**
 * Created by mazhi on 2018/7/12.
 */

public class FaceDetection {

    private native int loadModel(String modelDir);

//    private native int loadModelv2(String modelDir,int type);

    private native int[] detectFace(byte[] rgb24, int width, int height, int widthStep);

    private native int[] detectFaceForBitmap(Bitmap bmp, int width, int height);

//    public native String getSerialNov2(int type);
    public native String getSerialNo(String path);
//    public native String getSerialNo();

    private static volatile FaceDetection instance = null;

    private boolean _inited = false;

    final int EACH_FACE_BUFFER_LEN = 18;

    private FaceDetection() {
    }

    public boolean getInited()
    {
        return _inited;
    }

    public static FaceDetection getInstance() {
        if (instance == null) {
            synchronized (FaceDetection.class) {
                if (instance == null) {
                    instance = new FaceDetection();
                }
            }
        }
        return instance;
    }

    private FaceModel[] createFaceModelFromIntArray(int[] results)
    {
        int faceCount = results[0];
        FaceModel[] faceModels = null;
        if (faceCount>0)
        {
            faceModels=new FaceModel[faceCount];
            for (int i = 0; i < faceCount; i++) {
                FaceModel item = new FaceModel();
                item.rtFace = new FaceFeatureRectangle();
                item.rtFace.x = results[i * EACH_FACE_BUFFER_LEN + 1];
                item.rtFace.y = results[i * EACH_FACE_BUFFER_LEN + 2];
                item.rtFace.width = results[i * EACH_FACE_BUFFER_LEN + 3];
                item.rtFace.height = results[i * EACH_FACE_BUFFER_LEN + 4];
                item.ptLeftEye = new FaceFeaturePoint();
                item.ptLeftEye.x = results[i * EACH_FACE_BUFFER_LEN + 5];
                item.ptLeftEye.y = results[i * EACH_FACE_BUFFER_LEN + 6];
                item.ptRightEye = new FaceFeaturePoint();
                item.ptRightEye.x = results[i * EACH_FACE_BUFFER_LEN + 7];
                item.ptRightEye.y = results[i * EACH_FACE_BUFFER_LEN + 8];
                item.ptNose=new FaceFeaturePoint();
                item.ptNose.x=results[i*EACH_FACE_BUFFER_LEN+9];
                item.ptNose.y=results[i*EACH_FACE_BUFFER_LEN+10];
                item.ptMouthLeft=new FaceFeaturePoint();
                item.ptMouthLeft.x=results[i*EACH_FACE_BUFFER_LEN+11];
                item.ptMouthLeft.y=results[i*EACH_FACE_BUFFER_LEN+12];
                item.ptRightEye=new FaceFeaturePoint();
                item.ptRightEye.x=results[i*EACH_FACE_BUFFER_LEN+13];
                item.ptRightEye.y=results[i*EACH_FACE_BUFFER_LEN+14];
                item.roll=results[i*EACH_FACE_BUFFER_LEN+15];
                item.yaw=results[i*EACH_FACE_BUFFER_LEN+16];
                item.pitch=results[i*EACH_FACE_BUFFER_LEN+17];
                item.conf=results[i*EACH_FACE_BUFFER_LEN+18];
                faceModels[i]=item;
            }

        }
        return faceModels;
    }


    /**
     * @param modelPath 模型所在路径，deta.bin,deta.param等模型所在路径
     * @return 加载成功true, 失败false
     */
    public boolean init(String modelPath) {
        if (!_inited) {
            if (loadModel(modelPath) > 0) {
                _inited = true;
            }
//            int load=loadModelv2(modelPath,1);
//            if ( load > 0) {
//                _inited = true;
//            }
        }
        return _inited;
    }

    /**
     * @param bmp 检测图片Bitmap
     * @return 人脸模型,null为未检测到人脸
     * @throws Exception 当未调用init方法加载模型库时抛出异常
     */
    public FaceModel[] detectFaceModel(Bitmap bmp) throws Exception {
        if (!_inited)
            throw new Exception("算法模型未加载,请调用init方法加载模型");
        FaceModel[] faceModels = null;
        if (bmp != null) {
            int[] results = detectFaceForBitmap(bmp, bmp.getWidth(), bmp.getHeight());
            int faceCount = results[0];
            if (faceCount > 0) {
                faceModels = createFaceModelFromIntArray(results);
            }
        }
        return faceModels;
    }

    /**
     * @param rgb24 bitmap的数据区，不包含bitmap54个字节头
     * @param width 图片宽
     * @param height 图片高
     * @param widthStep 图片跨度 参考http://ranlic.iteye.com/blog/1313735
     * @return 人脸模型,null为未检测到人脸
     * @throws Exception 当未调用init方法加载模型库时抛出异常
     */
    public FaceModel[] detectFaceModel(byte[] rgb24, int width, int height, int widthStep) throws Exception
    {
        if (!_inited)
            throw new Exception("算法模型未加载,请调用init方法加载模型");
        FaceModel[] faceModels = null;
        if (rgb24 != null) {
            int[] results = detectFace(rgb24, width, height, widthStep);
            int faceCount = results[0];
            if (faceCount > 0) {
                faceModels = createFaceModelFromIntArray(results);
            }
        }
        return faceModels;
    }


}
